/**
 * 
 */
package org.vidyakiran.app.server.domain.entity;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Basic;
import javax.validation.constraints.Size;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.OneToMany;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;

import org.datanucleus.jpa.annotations.Extension;
import org.vidyakiran.app.server.domain.reference.OrganisationType;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Text;

/**
 * @author Harpreet
 *
 */
@Entity
public class Organisation implements Serializable {

	private static final long serialVersionUID = -314967958836444731L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Key id;
	
	@Basic
	@Size(max = 4,  message="")
	private String name;
	
	@Basic
	private Date registeredDate;
	
	@Basic
	@Extension(vendorName="datanucleus", key="gae.unindexed", value="true")
	private String registrationNumber;
	
	@Basic
	private String panNumber;
	
	@Basic
	private String locationId;

	
	public String getLocationId() {
		return locationId;
	}

	public void setLocationId(String locationId) {
		this.locationId = locationId;
	}

	@Basic
	@Extension(vendorName="datanucleus", key="gae.unindexed", value="true")
	private String trustNumber;

	@Basic
	@Extension(vendorName="datanucleus", key="gae.unindexed", value="true")
	private String tanNumber;
	
	@Lob
	@Extension(vendorName="datanucleus", key="gae.unindexed", value="true")
	private Text orgHistory;

	@Basic
	@Extension(vendorName="datanucleus", key="gae.unindexed", value="true")
	private Date creationDate;
	
	@Basic
	@Extension(vendorName="datanucleus", key="gae.unindexed", value="true")
	private Date lastModifiedDate;
	
	private OrganisationType organisationType;
	
	@OneToMany(cascade = CascadeType.ALL, mappedBy = "organisation", fetch = FetchType.LAZY)
	private Set<OrganisationAddress> address;

	@OneToMany(cascade = CascadeType.ALL, mappedBy = "organisation", fetch = FetchType.LAZY)
	private Set<OrganisationContact> contacts;

	@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "organisation", fetch = FetchType.LAZY)
	private Set<VolunteeringActivity> activities;

	/**
	 * This method updates the time stamps, creation date and lastmodified date. 
	 */
	@PrePersist
	@PreUpdate
	public void updatePreSave() {
		Date today = Calendar.getInstance().getTime();
		if(id == null) {
			creationDate = today;
		}
		lastModifiedDate = today;
	}
	
	/**
	 * @return the id
	 */
	public Key getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(Key id) {
		this.id = id;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the registeredDate
	 */
	public Date getRegisteredDate() {
		return registeredDate;
	}

	/**
	 * @param registeredDate the registeredDate to set
	 */
	public void setRegisteredDate(Date registeredDate) {
		this.registeredDate = registeredDate;
	}

	/**
	 * @return the registrationNumber
	 */
	public String getRegistrationNumber() {
		return registrationNumber;
	}

	/**
	 * @param registrationNumber the registrationNumber to set
	 */
	public void setRegistrationNumber(String registrationNumber) {
		this.registrationNumber = registrationNumber;
	}

	/**
	 * @return the panNumber
	 */
	public String getPanNumber() {
		return panNumber;
	}

	/**
	 * @param panNumber the panNumber to set
	 */
	public void setPanNumber(String panNumber) {
		this.panNumber = panNumber;
	}

	/**
	 * @return the trustNumber
	 */
	public String getTrustNumber() {
		return trustNumber;
	}

	/**
	 * @param trustNumber the trustNumber to set
	 */
	public void setTrustNumber(String trustNumber) {
		this.trustNumber = trustNumber;
	}

	/**
	 * @return the tanNumber
	 */
	public String getTanNumber() {
		return tanNumber;
	}

	/**
	 * @param tanNumber the tanNumber to set
	 */
	public void setTanNumber(String tanNumber) {
		this.tanNumber = tanNumber;
	}

	/**
	 * @return the orgHistory
	 */
	public Text getOrgHistory() {
		return orgHistory;
	}

	/**
	 * @param orgHistory the orgHistory to set
	 */
	public void setOrgHistory(Text orgHistory) {
		this.orgHistory = orgHistory;
	}

	/**
	 * @return the creationDate
	 */
	public Date getCreationDate() {
		return creationDate;
	}

	/**
	 * @param creationDate the creationDate to set
	 */
	public void setCreationDate(Date creationDate) {
		this.creationDate = creationDate;
	}

	/**
	 * @return the lastModifiedDate
	 */
	public Date getLastModifiedDate() {
		return lastModifiedDate;
	}

	/**
	 * @param lastModifiedDate the lastModifiedDate to set
	 */
	public void setLastModifiedDate(Date lastModifiedDate) {
		this.lastModifiedDate = lastModifiedDate;
	}

	/**
	 * @return the organisationType
	 */
	public OrganisationType getOrganisationType() {
		return organisationType;
	}

	/**
	 * @param organisationType the organisationType to set
	 */
	public void setOrganisationType(OrganisationType organisationType) {
		this.organisationType = organisationType;
	}

	/**
	 * @return the address
	 */
	public Set<OrganisationAddress> getAddress() {
		return address;
	}

	/**
	 * @param address the address to set
	 */
	public void setAddress(Set<OrganisationAddress> address) {
		this.address = address;
	}

	/**
	 * @return the contacts
	 */
	public Set<OrganisationContact> getContacts() {
		return contacts;
	}

	/**
	 * @param contacts the contacts to set
	 */
	public void setContacts(Set<OrganisationContact> contacts) {
		this.contacts = contacts;
	}

	/**
	 * @return the activities
	 */
	public Set<VolunteeringActivity> getActivities() {
		if(activities == null) {
			activities = new HashSet<VolunteeringActivity>();
		}
		return activities;
	}

	/**
	 * @param activities the activities to set
	 */
	public void setActivities(Set<VolunteeringActivity> activities) {
		this.activities = activities;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((creationDate == null) ? 0 : creationDate.hashCode());
		result = prime * result
				+ ((lastModifiedDate == null) ? 0 : lastModifiedDate.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result
				+ ((orgHistory == null) ? 0 : orgHistory.hashCode());
		result = prime
				* result
				+ ((organisationType == null) ? 0 : organisationType.hashCode());
		result = prime * result
				+ ((panNumber == null) ? 0 : panNumber.hashCode());
		result = prime * result
				+ ((registeredDate == null) ? 0 : registeredDate.hashCode());
		result = prime
				* result
				+ ((registrationNumber == null) ? 0 : registrationNumber
						.hashCode());
		result = prime * result
				+ ((tanNumber == null) ? 0 : tanNumber.hashCode());
		result = prime * result
				+ ((trustNumber == null) ? 0 : trustNumber.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Organisation other = (Organisation) obj;
		if (creationDate == null) {
			if (other.creationDate != null)
				return false;
		} else if (!creationDate.equals(other.creationDate))
			return false;
		if (lastModifiedDate == null) {
			if (other.lastModifiedDate != null)
				return false;
		} else if (!lastModifiedDate.equals(other.lastModifiedDate))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (orgHistory == null) {
			if (other.orgHistory != null)
				return false;
		} else if (!orgHistory.equals(other.orgHistory))
			return false;
		if (organisationType == null) {
			if (other.organisationType != null)
				return false;
		} else if (!organisationType.equals(other.organisationType))
			return false;
		if (panNumber == null) {
			if (other.panNumber != null)
				return false;
		} else if (!panNumber.equals(other.panNumber))
			return false;
		if (registeredDate == null) {
			if (other.registeredDate != null)
				return false;
		} else if (!registeredDate.equals(other.registeredDate))
			return false;
		if (registrationNumber == null) {
			if (other.registrationNumber != null)
				return false;
		} else if (!registrationNumber.equals(other.registrationNumber))
			return false;
		if (tanNumber == null) {
			if (other.tanNumber != null)
				return false;
		} else if (!tanNumber.equals(other.tanNumber))
			return false;
		if (trustNumber == null) {
			if (other.trustNumber != null)
				return false;
		} else if (!trustNumber.equals(other.trustNumber))
			return false;
		return true;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Organisation ["
				+ (creationDate != null ? "creationDate=" + creationDate + ", "
						: "")
				+ (id != null ? "id=" + id + ", " : "")
				+ (lastModifiedDate != null ? "modifiedDate=" + lastModifiedDate + ", "
						: "")
				+ (name != null ? "name=" + name + ", " : "")
				+ (orgHistory != null ? "orgHistory=" + orgHistory + ", " : "")
				+ (organisationType != null ? "organisationType="
						+ organisationType + ", " : "")
				+ (panNumber != null ? "panNumber=" + panNumber + ", " : "")
				+ (registeredDate != null ? "registeredDate=" + registeredDate
						+ ", " : "")
				+ (registrationNumber != null ? "registrationNumber="
						+ registrationNumber + ", " : "")
				+ (tanNumber != null ? "tanNumber=" + tanNumber + ", " : "")
				+ (trustNumber != null ? "trustNumber=" + trustNumber : "")
				+ "]";
	}
	
}
